
#include "common.h"
#include "conf.h"

static pthread_mutex_t lock;
static char *time_to_string(const time_t *time, char *buf, size_t size);

void log_init(void) 
{
	assert(conf);
	
	if(!error_logp) {
		if(conf->log.error) {
			error_logp = fopen(conf->log.error, "a");
			assert(error_logp);
			setvbuf(error_logp, NULL,  _IONBF, 0);
		}
	}
	if(!debug_logp) {
		if(conf->log.debug) {
			debug_logp = fopen(conf->log.debug, "a");
			if(debug_logp == NULL) {
				fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, (char *)strerror(errno));
				abort();
			}
			setvbuf(debug_logp, NULL,  _IONBF, 0);
		}
	}
	pthread_mutex_init(&lock, NULL);
	debug_log(1, "%s\n", "success init log system");
}


void vlog_debug(FILE *file, const int level, const char *format,...)
{
	assert(conf);
	if(!file) 
		return;
	if(level == 0) {
		error_log(errno, format);
		return;
	}
	if(level > conf->server.debug_level) 
		return;

	char new_format[MAX_BUFFER];
	time_t now = time(NULL);
	char buf[MAX_BUFFER];
	
	time_to_string(&now, buf, MAX_BUFFER);
	pthread_mutex_lock(&lock);
	va_list  va;
	va_start(va, format);
	snprintf(new_format, MAX_BUFFER - 1 ,  "[%s] %s", buf, format);
	if(vfprintf(file, new_format, va) < 0)
		fprintf(stderr, "Warning. [%s %d] %s\n", __FILE__, __LINE__, (char *)strerror(errno));
	va_end(va);
	pthread_mutex_unlock(&lock);
}

void error_log(int err, const char *format, ...)
{
	char new_format[MAX_BUFFER];
	char error_buf[1024];
	time_t now = time(NULL);
	char buf[MAX_BUFFER];
    
	time_to_string(&now, buf, MAX_BUFFER);
	if(0 == strerror_r(err, error_buf, 1023)) {
		pthread_mutex_lock(&lock);
		va_list  va;
		va_start(va, format);
		snprintf(new_format, MAX_BUFFER - 1 ,  "[%s] %s, %s", buf, error_buf, format);
		if(vfprintf(error_logp, new_format, va) < 0)
			fprintf(stderr, "Warning. [%s %d] %s\n", __FILE__, __LINE__, strerror(errno));
		va_end(va);
		pthread_mutex_unlock(&lock);
	}
}


static char *time_to_string(const time_t *time, char *buf, size_t size)
{
	const char *spec = "%a, %d %b %G %H:%M:%S GMT";
	const char *spec1 = "%d/%b/%G/%H:%M:%S";
	struct tm *t = NULL;
	int res;

	memset(buf, 0, MAX_BUFFER);
	t = gmtime(time);
	res = strftime(buf, MAX_BUFFER, spec1, t);
	buf[res] = '\0';
	return buf;
}
